home *** CD-ROM | disk | FTP | other *** search
- /*
- * netDF.c --
- *
- * The main routines for the device driver for the
- * DEC FDDI controller 700.
- *
- *
- * Copyright 1992 Regents of the University of Californiaf
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/net/ds5000.md/netDF.c,v 1.4 92/07/17 17:25:10 jhh Exp $";
- #endif not lint
-
- #include <sprite.h>
- #include <sys.h>
- #include <list.h>
- #include <netInt.h>
- #include <vm.h>
- #include <vmMach.h>
- #include <mach.h>
- #include <machMon.h>
- #include <dbg.h>
- #include <assert.h>
- #include <dev/fddi.h>
- #include <fmt.h>
- #include <netDFInt.h>
-
- #ifdef sun4c
- #include <devSCSIC90.h>
- #endif
-
- /*
- * Macro to get the next descriptor on the COMMAND ring.
- */
- #define NEXT_CMD_DESC(p) ( (((p)+1) > statePtr->comLastPtr) ? \
- statePtr->comRingPtr : ((p)+1))
- /*
- * Macro to access the buffer corresponding to the CMD descriptor.
- */
- #define CmdBufFromDesc(statePtr, descPtr) \
- (statePtr->comBufPtr + \
- (NET_DF_COMMAND_BUF_SIZE * (unsigned long)(descPtr - statePtr->comRingPtr)))
-
-
- static void NetDFRestartCallback _ARGS_((ClientData data,
- Proc_CallInfo *infoPtr));
- /*
- * Debug flag
- */
- int netDFDebug;
-
-
- #ifdef NET_DF_USE_UNCACHED_MEM
-
- NetDFState uncachedNetDFState[3];
-
- #else
-
- extern Net_Interface *netInterfaces[NET_MAX_INTERFACES];
- extern int netNumInterfaces;
-
- #endif
-
- void NetDFRestart();
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFPrintStateAddrs --
- *
- * Print out the addresses of the NetDFState structs corresponding
- * to the FDDI interfaces. Used for debugging only.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Prints to stdout.
- *
- *----------------------------------------------------------------------
- */
- void
- NetDFPrintStateAddrs()
- {
- /*
- * When the stack gets trashed, etc., it's hard to get a handle
- * on the state structure being used. So you can get the address
- * in kgdb by calling this routine.
- */
- #ifdef NET_DF_USE_UNCACHED_MEM
- printf("slot 0: 0x%x\tslot 1: 0x%x\tslot 2: 0x%x\n",
- &uncachedNetDFState[0], &uncachedNetDFState[1],
- &uncachedNetDFState[2]);
- #else
- int i;
-
- for (i = 0; i < netNumInterfaces; i++) {
- if (netInterfaces[i]->netType == NET_NETWORK_FDDI) {
- printf("slot %d: statePtr: 0x%x\n",
- netInterfaces[i]->unit, netInterfaces[i]->interfaceData);
- }
- }
- #endif
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFInit --
- *
- * Initialize the DEC FDDIcontroller 700 board.
- *
- * Results:
- * SUCCESS if the controller was found and initialized,
- * FAILURE otherwise.
- *
- * Side effects:
- * Initializes the NetDFState record, as well as the chip.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFInit(interPtr)
- Net_Interface *interPtr; /* Network interface. */
- {
- register NetDFState *statePtr;
- List_Links *itemPtr;
- register int i;
- ReturnStatus status;
-
- MASTER_LOCK(&interPtr->mutex)
-
- /*
- * Just to make sure that the structures are the correct sizes.
- */
- assert(sizeof(Net_DFReg) == 2);
- assert(sizeof(NetDFCommandDesc) == 16);
- assert(sizeof(NetDFHostRcvDesc) == 16);
- assert(sizeof(NetDFSmtRcvDesc) == 16);
- assert(sizeof(NetDFSmtXmtDesc) == 16);
- assert(sizeof(NetDFRmcXmtDesc) == 16);
- assert(sizeof(NetDFUnsolDesc) == 16);
-
- netDFDebug = NET_DF_DEBUG_OFF;
-
- MAKE_NOTE("Initializing adapter.");
-
- #ifdef NET_DF_USE_UNCACHED_MEM
- statePtr = &uncachedNetDFState[(int)interPtr->ctrlAddr];
- statePtr = (NetDFState *)MACH_UNCACHED_ADDR(statePtr);
- #else
- statePtr = (NetDFState *) malloc (sizeof(NetDFState));
- #endif
- bzero((char *) statePtr, sizeof(NetDFState));
-
- statePtr->running = FALSE;
- status = NetDFMachInit(interPtr, statePtr);
- if (status != SUCCESS) {
- MASTER_UNLOCK(&interPtr->mutex);
- #ifndef NET_DF_USE_UNCACHED_MEM
- free((char *) statePtr);
- #endif
- return status;
- }
-
- /*
- * Initialize the transmission list.
- */
- statePtr->xmitList = &statePtr->xmitListHdr;
- List_Init(statePtr->xmitList);
- statePtr->xmitFreeList = &statePtr->xmitFreeListHdr;
- List_Init(statePtr->xmitFreeList);
-
- for (i = 0; i < NET_DF_NUM_XMIT_ELEMENTS; i++) {
- itemPtr = (List_Links *) malloc(sizeof(NetDFXmtElement)),
- List_InitElement(itemPtr);
- List_Insert(itemPtr, LIST_ATREAR(statePtr->xmitFreeList));
- }
-
- interPtr->init = NetDFInit;
- interPtr->output = NetDFOutput;
- interPtr->intr = NetDFIntr;
- interPtr->ioctl = NetDFIOControl;
- interPtr->reset = Net_DFRestart; /**/
- interPtr->getStats = NetDFGetStats;
- interPtr->netType = NET_NETWORK_FDDI;
- interPtr->maxBytes = NET_FDDI_MAX_BYTES - sizeof(Net_FDDIHdr);
- interPtr->minBytes = NET_FDDI_MIN_BYTES;
- interPtr->interfaceData = (ClientData) statePtr;
-
- statePtr->interPtr = interPtr;
- statePtr->recvMemInitialized = FALSE;
- statePtr->recvMemAllocated = FALSE;
- statePtr->xmitMemInitialized = FALSE;
- statePtr->xmitMemAllocated = FALSE;
- statePtr->resetPending = FALSE;
- statePtr->curScatGathPtr = (Net_ScatterGather *) NIL;
-
- /*
- * Initialize buffer for storing the results of an INIT command.
- * These results will later be used by a PARAM command.
- */
- statePtr->initComPtr = (NetDFInitCommand *)malloc(NET_DF_COMMAND_BUF_SIZE);
-
- /*
- * Reset the world.
- */
- NetDFReset(interPtr);
-
-
- /*
- * Now we are running.
- */
- statePtr->running = TRUE;
- statePtr->flags = NET_DF_FLAGS_NORMAL;
-
- MASTER_UNLOCK(&interPtr->mutex);
-
- return (SUCCESS);
- }
-
- /*
- * Simple debug ring to hold strings.
- */
- char *netDFDebugRing[NET_DF_DEBUG_RING_SIZE];
- int netDFDebugRingIndex;
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFPrintDebugRing --
- *
- * Print out the contents of the debug ring, from most remote to
- * most recent in time.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Debug messages are printed.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- void
- NetDFPrintDebugRing(statePtr)
- register NetDFState *statePtr;
- {
- char *messagePtr;
- int index;
-
- index = netDFDebugRingIndex;
-
- printf("<---\n");
- while (TRUE) {
- /*
- * Start at the last one.
- */
- messagePtr = netDFDebugRing[index];
- if (messagePtr != NULL) {
- printf("%d\t%s\n", index, messagePtr);
- }
- index = (index + 1) % NET_DF_DEBUG_RING_SIZE;
- if (index == netDFDebugRingIndex) {
- break;
- }
- }
- printf("--->\n");
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFPrintRegContents --
- *
- * Print out the contents in each of the six registers on the adapter.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The register contents are printed.
- *
- *----------------------------------------------------------------------
- */
- void
- NetDFPrintRegContents(statePtr)
- register NetDFState *statePtr;
- {
- register unsigned short status;
-
- status = *(statePtr->regReset);
- printf("Reset: 0x%x\t", status);
- status = *(statePtr->regCtrlA);
- printf("CtrlA: 0x%x\t", status);
- status = *(statePtr->regCtrlB);
- printf("CtrlB: 0x%x\n", status);
- status = *(statePtr->regStatus);
- printf("Status: 0x%x\t", status);
- status = *(statePtr->regEvent);
- printf("Event: 0x%x\t", status);
- status = *(statePtr->regMask);
- printf("Mask: 0x%x\n", status);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFPrintErrLog --
- *
- * Print out selected contents of the error log. Error codes
- * are placed in a log buffer on the adapter when the
- * adapter goes wacky.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Error log contents are printed.
- *
- *----------------------------------------------------------------------
- */
- void
- NetDFPrintErrorLog(statePtr)
- register NetDFState *statePtr;
- {
- register volatile unsigned char *errPtr;
- register unsigned long large;
-
- /*
- * The internal code specifies a more detailed error than the
- * external code.
- */
- errPtr = statePtr->errLogPtr;
- large = (unsigned long)*(errPtr + NET_DF_MACH_ERR_INTERNAL_OFFSET);
- /*
- * The external code is the one that can be found in the STATUS
- * regsiter.
- */
- printf("Internal: 0x%x\t", large);
- large = (unsigned long)*(errPtr + NET_DF_MACH_ERR_EXTERNAL_OFFSET);
- printf("External: 0x%x\t", large);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFAssertState --
- *
- * If the adapter is not in the given state, then panic!
- *
- * Results:
- * None.
- *
- * Side effects:
- * We could panic.
- *
- *----------------------------------------------------------------------
- */
- void
- NetDFAssertState(statePtr, state)
- register NetDFState *statePtr;
- unsigned short state;
- {
- unsigned short status;
-
- status = *(statePtr->regStatus) & NET_DF_STATUS_ADAPTER_STATE;
- if (status != state) {
- status = status;
- panic("DEC FDDI: adapter in wrong state (is %x, want %x)\n",
- status, state);
- }
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFCommandTimeout --
- *
- * Wait for a command to finish. If it does not finish within
- * a finite time, then stop waiting and return an error.
- *
- * Results:
- * SUCCESS if the command finished within its allotted time,
- * and FAILURE otherwise.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFCommandTimeout(statePtr, comDescPtr)
- register NetDFState *statePtr;
- register volatile NetDFCommandDesc *comDescPtr;
- {
- register volatile Net_DFReg status;
- register volatile Net_DFReg event;
- register unsigned long n;
-
- /*
- * Clear the CMD_DONE bit, and give ownership of the command descriptor to
- * the adapter. Then poke the CTRLA register, telling it that we've set
- * up a command to be executed.
- */
- *(statePtr->regEvent) = NET_DF_EVENT_CMD_DONE;
- n = comDescPtr->command & NET_DF_COMMAND_MASK;
- comDescPtr->command = n | NET_DF_ADAPTER_OWN;
- *(statePtr->regCtrlA) |= NET_DF_CTRLA_CMD_POLL_DEMAND;
-
- /*
- * Wait for the CMD_DONE event.
- */
- status = FAILURE;
- for (n = 0; n < 10000000; n++) {
- event = *(statePtr->regEvent);
- if (event & NET_DF_EVENT_CMD_DONE) {
- /*
- * Clear the event we just noticed
- */
- *(statePtr->regEvent) = NET_DF_EVENT_CMD_DONE;
- status = SUCCESS;
- break;
- }
- }
-
- if (status == SUCCESS && comDescPtr->status == NET_DF_COMMAND_STATUS_OK) {
- return status;
- }
- NetDFPrintRegContents(statePtr);
- NetDFPrintErrorLog(statePtr);
- if (status == SUCCESS) {
- printf("DEC FDDI: command %d did not work\n",
- comDescPtr->command & NET_DF_COMMAND_MASK);
- } else {
- printf("DEC FDDI: command %d timed out\n",
- comDescPtr->command & NET_DF_COMMAND_MASK);
- }
- printf("command addr: 0x%x\n", comDescPtr);
- printf("command status: 0x%x\n", comDescPtr->status);
- printf("command field: 0x%x\n", comDescPtr->command);
- printf("bufAddr field: 0x%x\n", comDescPtr->bufAddr);
- return FAILURE;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFDoInitCommand --
- *
- * Execute the INIT command on the DEC FDDI adapter.
- *
- * Results:
- * SUCCESS if the INIT command succeeded, FAILURE otherwise.
- *
- * Side effects:
- * If successful, the adapter will transition to the INITIALIZED
- * state, and the interface will have its pointers updated with
- * the base addresses for the adapter rings and the link address
- * for the adapter. The link address is reported to the console.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFDoInitCommand(statePtr)
- register NetDFState *statePtr; /* Interface to FDDI adapter. */
- {
- register volatile NetDFInitCommand *comInitPtr;
- register volatile NetDFCommandDesc *comDescPtr;
- register char *linkAddr;
- register char *slotAddr;
- register int i;
- int slot;
- Mach_SlotInfo slotInfo;
- char buffer[32];
- ReturnStatus result;
-
- /*
- * The adapter must be in the UNINITIALIZED state.
- */
- NetDFAssertState(statePtr, NET_DF_STATE_UNINITIALIZED);
-
- comDescPtr = statePtr->comNextPtr;
- if ((comDescPtr->command & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- panic("DEC FDDI: Command Descriptor owned by adapter!");
- }
- statePtr->comNextPtr = NEXT_CMD_DESC(comDescPtr);
- comInitPtr = (NetDFInitCommand *)CmdBufFromDesc(statePtr, comDescPtr);
- /*
- * Set up a command descriptor for an INIT command.
- */
- comDescPtr->command = NET_DF_HOST_OWN | NET_DF_COMMAND_INIT;
- comDescPtr->status = 0x0;
- comDescPtr->bufAddr = (NET_DF_ULONG)comInitPtr;
-
- /*
- * Set up the command buffer with proper input values.
- */
- bzero((Address)comInitPtr, NET_DF_COMMAND_BUF_SIZE);
- comInitPtr->transmitMode = NET_DF_INIT_TRANSMIT_MODE;
- comInitPtr->rcvEntries = NET_DF_INIT_HOST_RCV_ENTRIES;
- Mach_EmptyWriteBuffer();
-
- result = NetDFCommandTimeout(statePtr, comDescPtr);
- if (result != SUCCESS) {
- panic("DEC FDDI: INIT command failed!\n");
- }
-
- /*
- * We should have transitioned into the INITIALIZED state.
- * Clear the STATE_CHANGE event bit.
- */
- NetDFAssertState(statePtr, NET_DF_STATE_INITIALIZED);
- *(statePtr->regEvent) = NET_DF_EVENT_STATE_CHANGE;
-
- /*
- * Extract and report the FDDI address.
- */
- linkAddr = (char *)comInitPtr->linkAddress;
- for (i = 0; i < 6; i++) {
- ((char *)&statePtr->fddiAddress)[i] = linkAddr[i];
- }
-
- slot = (int) statePtr->interPtr->ctrlAddr;
- slotAddr = statePtr->slotAddr;
- result = Mach_GetSlotInfo(slotAddr + NET_DF_MACH_OPTION_ROM_OFFSET,
- &slotInfo);
- if (result != SUCCESS) {
- return result;
- }
- (void) Net_FDDIAddrToString(&statePtr->fddiAddress, buffer);
- printf("FDDI in slot %d, address %s (%s %s %s %s)\n",
- slot, buffer, slotInfo.module, slotInfo.vendor,
- slotInfo.revision, slotInfo.type);
- result = Net_SetAddress(NET_ADDRESS_FDDI,
- (Address) &statePtr->fddiAddress,
- &statePtr->interPtr->netAddress[NET_PROTO_RAW]);
- if (result != SUCCESS) {
- panic("NetDFDoInitCommand: Net_SetAddress failed.\n");
- }
- /*
- * Save the INIT command buffer...we will need its values for
- * the PARAM command that gets done a little later. After the command
- * ring goes around once, this buffer becomes invalid.
- */
- bcopy(comInitPtr, statePtr->initComPtr, NET_DF_COMMAND_BUF_SIZE);
-
- return SUCCESS;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFDoModcamCommand --
- *
- * Execute the MODCAM command on the DEC FDDI adapter.
- *
- * Results:
- * SUCCESS if the MODCAM command succeeded, FAILURE otherwise.
- *
- * Side effects:
- * If successful, the adapter will be loaded with the default
- * CAM entries for address recognition (i.e.,
- * NET_DF_MODCAM_RING_PURGE, NET_DF_MODCAM_BEACON)
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFDoModcamCommand(statePtr)
- register NetDFState *statePtr; /* Interface to FDDI adapter. */
- {
- register volatile NetDFModcamCommand *comModcamPtr;
- register volatile NetDFCommandDesc *comDescPtr;
- register unsigned long *intAddr;
- ReturnStatus result;
-
- comDescPtr = statePtr->comNextPtr;
- if ((comDescPtr->command & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- panic("DEC FDDI: Command Descriptor owned by adapter!");
- }
- statePtr->comNextPtr = NEXT_CMD_DESC(comDescPtr);
- comModcamPtr = (NetDFModcamCommand *)CmdBufFromDesc(statePtr, comDescPtr);
- /*
- * Set up a command descriptor for a MODCAM command.
- */
- comDescPtr->command = NET_DF_HOST_OWN | NET_DF_COMMAND_MODCAM;
- comDescPtr->status = 0x0;
- comDescPtr->bufAddr = (NET_DF_ULONG)comModcamPtr;
-
- /*
- * Set up the command buffer with proper input values.
- */
- bzero((Address)comModcamPtr, NET_DF_COMMAND_BUF_SIZE);
-
- intAddr = (unsigned long *)comModcamPtr;
- intAddr[0] = NET_DF_MODCAM_BEACON_LOW;
- intAddr[1] = NET_DF_MODCAM_BEACON_HIGH;
- intAddr[2] = NET_DF_MODCAM_RING_PURGE_LOW;
- intAddr[3] = NET_DF_MODCAM_RING_PURGE_HIGH;
- Mach_EmptyWriteBuffer();
-
- result = NetDFCommandTimeout(statePtr, comDescPtr);
- if (result != SUCCESS) {
- printf("DEC FDDI: MODCAM command did not work!\n");
- }
- return result;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFDoStatusCommand --
- *
- * Execute the STATUS command on the DEC FDDI adapter.
- *
- * Results:
- * SUCCESS if the STATUS command succeeded, FAILURE otherwise.
- *
- * Side effects:
- * The statusComPtr slot of the statePtr is updated with the
- * results of the status command.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFDoStatusCommand(statePtr)
- register NetDFState *statePtr; /* Interface to FDDI adapter. */
- {
- register volatile NetDFStatusCommand *comStatusPtr;
- register volatile NetDFCommandDesc *comDescPtr;
- ReturnStatus result;
-
- comDescPtr = statePtr->comNextPtr;
- if ((comDescPtr->command & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- panic("DEC FDDI: Command Descriptor owned by adapter!");
- }
- statePtr->comNextPtr = NEXT_CMD_DESC(comDescPtr);
- comStatusPtr = (NetDFStatusCommand *)CmdBufFromDesc(statePtr, comDescPtr);
- /*
- * Set up a command descriptor for a STATUS command.
- */
- comDescPtr->command = NET_DF_HOST_OWN | NET_DF_COMMAND_STATUS;
- comDescPtr->status = 0x0;
- comDescPtr->bufAddr = (NET_DF_ULONG)comStatusPtr;
-
- /*
- * Set up the command buffer with proper input values.
- * For a status command, the adapter fills it all in.
- */
- bzero((Address)comStatusPtr, NET_DF_COMMAND_BUF_SIZE);
- Mach_EmptyWriteBuffer();
-
- result = NetDFCommandTimeout(statePtr, comDescPtr);
- if (result != SUCCESS) {
- printf("DEC FDDI: STATUS command did not work, darnit!\n");
- return FAILURE;
- }
-
- printf("LED state 0x%x\t", comStatusPtr->ledState);
- printf("Link state 0x%x\t", comStatusPtr->linkState);
- printf("Phy state 0x%x\n", comStatusPtr->phyState);
- return SUCCESS;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFDoRdcamCommand --
- *
- * Execute the RDCAM command on the DEC FDDI adapter.
- *
- * Results:
- * SUCCESS if the RDCAM command succeeded, FAILURE otherwise.
- *
- * Side effects:
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFDoRdcamCommand(statePtr)
- register NetDFState *statePtr;
- {
- register volatile NetDFRdcamCommand *comRdcamPtr;
- register volatile NetDFCommandDesc *comDescPtr;
- register int j, k;
- register char *addr;
- char buffer[32];
- Net_FDDIAddress fddiAddress;
- ReturnStatus result;
-
- comDescPtr = statePtr->comNextPtr;
- if ((comDescPtr->command & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- panic("DEC FDDI: Command Descriptor owned by adapter!");
- }
- statePtr->comNextPtr = NEXT_CMD_DESC(comDescPtr);
- comRdcamPtr = (NetDFRdcamCommand *)CmdBufFromDesc(statePtr, comDescPtr);
- /*
- * Set up a command descriptor for a RDCAM command.
- */
- comDescPtr->command = NET_DF_HOST_OWN | NET_DF_COMMAND_RDCAM;
- comDescPtr->status = 0x0;
- comDescPtr->bufAddr = (NET_DF_ULONG)comRdcamPtr;
-
- /*
- * Set up the command buffer with proper input values.
- */
- bzero((Address)comRdcamPtr, NET_DF_COMMAND_BUF_SIZE);
- Mach_EmptyWriteBuffer();
-
- result = NetDFCommandTimeout(statePtr, comDescPtr);
- if (result != SUCCESS) {
- printf("DEC FDDI: shoot! the RDCAM command did not work!\n");
- return result;
- }
- /*
- * Print out the addresses returned in the buffer.
- */
- for (j = 0; j < 2; j++) {
- addr = (char *)(comRdcamPtr + j);
- for (k = 0; k < 6; k++) {
- ((char *)&fddiAddress)[k] = addr[k];
- }
- (void) Net_FDDIAddrToString(&fddiAddress, buffer);
- DFprintf("RDCAM entry %d addr 0x%x -- %s\n", j,
- comRdcamPtr + j, buffer);
- }
- return SUCCESS;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFDoParamCommand --
- *
- * Execute the PARAM command on the DEC FDDI adapter.
- *
- * Results:
- * SUCCESS if the PARAM command succeeded, FAILURE otherwise.
- *
- * Side effects:
- * If successful, the adapter will transition to the RUNNING state
- * and connect to the FDDI ring. Processing of receive and
- * transmit frames will begin.
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFDoParamCommand(statePtr)
- register NetDFState *statePtr; /* Interface to FDDI adapter. */
- {
- register volatile NetDFParamCommand *comParamPtr;
- register volatile NetDFCommandDesc *comDescPtr;
- ReturnStatus result;
-
- comDescPtr = statePtr->comNextPtr;
- if ((comDescPtr->command & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- panic("DEC FDDI: Command Descriptor owned by adapter!");
- }
- statePtr->comNextPtr = NEXT_CMD_DESC(comDescPtr);
- comParamPtr = (NetDFParamCommand *)CmdBufFromDesc(statePtr, comDescPtr);
- /*
- * Set up a command descriptor for a PARAM command.
- */
- comDescPtr->command = NET_DF_HOST_OWN | NET_DF_COMMAND_PARAM;
- comDescPtr->status = 0x0;
- comDescPtr->bufAddr = (NET_DF_ULONG)comParamPtr;
-
- /*
- * Set up the command buffer with proper input values.
- * Most of these values are default values that are given
- * to us from the adapter using the INIT command.
- */
- bzero((Address)comParamPtr, NET_DF_COMMAND_BUF_SIZE);
- comParamPtr->loopMode = NET_DF_NO_LOOP;
- comParamPtr->tMax = statePtr->initComPtr->defaultTMax;
- comParamPtr->tReq = statePtr->initComPtr->defaultTReq;
- comParamPtr->tvx = statePtr->initComPtr->defaultTvx;
- comParamPtr->lemThresh = statePtr->initComPtr->lemThresh;
- comParamPtr->stationID.count1 = statePtr->initComPtr->stationID.count1;
- comParamPtr->stationID.count2 = statePtr->initComPtr->stationID.count2;
- comParamPtr->tokenTimeout = statePtr->initComPtr->tokenTimeout;
- comParamPtr->ringPurgeEnable = statePtr->initComPtr->ringPurgeEnable;
- Mach_EmptyWriteBuffer();
-
- result = NetDFCommandTimeout(statePtr, comDescPtr);
- if (result != SUCCESS) {
- printf("DEC FDDI: uh oh...the PARAM command did not work\n");
- return result;
- }
- /*
- * We should have transitioned into the RUNNING state.
- * Make sure to clear the STATE_CHANGE event bit.
- */
- NetDFAssertState(statePtr, NET_DF_STATE_RUNNING);
- *(statePtr->regEvent) = NET_DF_EVENT_STATE_CHANGE;
- return SUCCESS;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFDoModpromCommand --
- *
- * Execute the MODPROM command on the DEC FDDI adapter.
- *
- * Results:
- * SUCCESS if the MODPROM command succeeded, FAILURE otherwise.
- *
- * Side effects:
- *
- *----------------------------------------------------------------------
- */
- ReturnStatus
- NetDFDoModpromCommand(statePtr)
- register NetDFState *statePtr;
- {
- register volatile NetDFModpromCommand *comModpromPtr;
- register volatile NetDFCommandDesc *comDescPtr;
- ReturnStatus result;
-
- comDescPtr = statePtr->comNextPtr;
- if ((comDescPtr->command & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- panic("DEC FDDI: Command Descriptor owned by adapter!");
- }
- statePtr->comNextPtr = NEXT_CMD_DESC(comDescPtr);
- comModpromPtr = (NetDFModpromCommand *)
- CmdBufFromDesc(statePtr, comDescPtr);
- /*
- * Set up a command descriptor for a MODPROM command.
- */
- comDescPtr->command = NET_DF_HOST_OWN | NET_DF_COMMAND_MODPROM;
- comDescPtr->status = 0x0;
- comDescPtr->bufAddr = (NET_DF_ULONG)comModpromPtr;
-
- /*
- * Set up the command buffer with proper input values.
- */
- bzero((Address)comModpromPtr, NET_DF_COMMAND_BUF_SIZE);
-
- comModpromPtr->llcPromEnable = NET_DF_FALSE;
- comModpromPtr->smtPromEnable = NET_DF_FALSE;
- comModpromPtr->llcMultiEnable = NET_DF_FALSE;
- comModpromPtr->llcBroadEnable = NET_DF_FALSE;
-
- result = NetDFCommandTimeout(statePtr, comDescPtr);
- if (result != SUCCESS) {
- printf("DEC FDDI: MODPROM command didn't work\n");
- return FAILURE;
- }
- return SUCCESS;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * ProcessUnsolicited --
- *
- * Process the UNSOLICITED ring entries. We just report
- * what they say; we don't really act on them.
- *
- * Results:
- * SUCCESS if we succeeded to read them, FAILURE otherwise.
- *
- * Side effects:
- *
- *----------------------------------------------------------------------
- */
- static ReturnStatus
- ProcessUnsolicited(statePtr)
- register NetDFState *statePtr;
- {
- register volatile NetDFUnsolDesc *descPtr;
- register Net_FDDIAddress *addrPtr;
- register NetDFDirectedBeacon *beaconPtr;
- char buffer[32];
-
- static char *eventNames[] = {
- "UNDEFINED",
- "RING_INIT_INIT",
- "RING_INIT_RCV",
- "BEACON_INIT",
- "DUP_ADDR",
- "DUP_TOKEN",
- "PURGE_ERROR",
- "STRIP_ERROR",
- "OP_OSCILLAT",
- "BEACON_RCV",
- "PC_TRACE_INIT",
- "PC_TRACE_RECV",
- "XMT_UNDERRUN",
- "XMT_FAILURE",
- "RCV_OVERRUN"
- };
-
- descPtr = statePtr->unsolNextDescPtr;
-
- if ((descPtr->own & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- if (statePtr->lastUnsolCnt == 0) {
- printf("DEC FDDI: Unsolicited Descriptor owned by adapter.\n");
- return (FAILURE);
- } else {
- statePtr->lastUnsolCnt == 0;
- return (SUCCESS);
- }
- }
- statePtr->lastUnsolCnt = 0;
- while (TRUE) {
- switch ((int) descPtr->eventID) {
- case NET_DF_UNSOL_UNDEFINED:
- case NET_DF_UNSOL_RING_INIT_INIT:
- case NET_DF_UNSOL_RING_INIT_RCV:
- case NET_DF_UNSOL_BEACON_INIT:
- case NET_DF_UNSOL_DUP_ADDR:
- case NET_DF_UNSOL_DUP_TOKEN:
- case NET_DF_UNSOL_PURGE_ERROR:
- case NET_DF_UNSOL_STRIP_ERROR:
- case NET_DF_UNSOL_OP_OSCILLAT:
- case NET_DF_UNSOL_PC_TRACE_INIT:
- case NET_DF_UNSOL_PC_TRACE_RECV:
- case NET_DF_UNSOL_XMT_UNDERRUN:
- case NET_DF_UNSOL_XMT_FAILURE:
- case NET_DF_UNSOL_RCV_OVERRUN:
- printf("DEC FDDI: Received Unsolicited Event: %s\n",
- eventNames[descPtr->eventID]);
- break;
- case NET_DF_UNSOL_BEACON_RCV:
- printf("DEC FDDI: Received Unsolicited Event: %s\n",
- eventNames[descPtr->eventID]);
- beaconPtr = (NetDFDirectedBeacon *)
- (descPtr->bufAddr + statePtr->slotAddr);
- addrPtr = (Net_FDDIAddress *)beaconPtr->sourceAddr;
- (void) Net_FDDIAddrToString(addrPtr, buffer);
- printf(" Source Address: %s", buffer);
- addrPtr = (Net_FDDIAddress *)beaconPtr->una;
- (void) Net_FDDIAddrToString(addrPtr, buffer);
- printf(" UNA of Source: %s", buffer);
-
- break;
- default:
- printf("DEC FDDI: Unknown Unsolicited Event.\n");
- break;
- }
- statePtr->lastUnsolCnt++;
- descPtr = (descPtr + 1) > statePtr->unsolLastDescPtr ?
- statePtr->unsolFirstDescPtr : (descPtr + 1);
- if ((descPtr->own & NET_DF_OWN) == NET_DF_ADAPTER_OWN) {
- break;
- }
- }
- statePtr->unsolNextDescPtr = descPtr;
- return (SUCCESS);
- }
-
- static void FinishReset();
-
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFReset --
- *
- * Reset the interface.
- *
- * Results:
- * None.
- *
- * Side effects:
- * All of the pointers in the interface structure are initialized.
- *
- *----------------------------------------------------------------------
- */
-
- void
- NetDFReset(interPtr)
- Net_Interface *interPtr; /* Interface to reset. */
- {
- register NetDFState *statePtr;
- register int i;
- unsigned short status;
- Boolean test;
-
- statePtr = (NetDFState *) interPtr->interfaceData;
- /*
- * If there isn't a reset pending already, and the chip is currently
- * transmitting then just set the pending flag. With any luck
- * this mechanism will prevent the chip from being reset right in
- * the middle of a packet.
- */
-
- if (!(statePtr->resetPending) && (statePtr->transmitting)) {
- printf("Deferring reset.\n");
- statePtr->resetPending = TRUE;
- return;
- }
- statePtr->resetPending = FALSE;
-
- /*
- * Reset (and stop) the chip.
- */
- interPtr->flags &= ~NET_IFLAGS_RUNNING;
- /*
- * Reset the chip. First put the chip into driver mode by setting
- * the DRIVER_MODE bit in PORT_CONTROL_B, and then set and clear
- * the RESET bit in PORT_RESET. The chip will then run self-tests,
- * and, if the self-tests pass, should transition to UNINITIALIZED
- * in less than 30 seconds. Otherwise it has failed the self-tests,
- * and will remain in RESETTING.
- */
-
- NET_DF_DISABLE_ALL_INT(*(statePtr->regMask));
- Mach_EmptyWriteBuffer();
-
- status = *(statePtr->regStatus);
- status = (status & NET_DF_STATUS_ADAPTER_STATE) >> 8;
-
- *(statePtr->regCtrlB) = NET_DF_CTRLB_DRIVER_MODE;
- Mach_EmptyWriteBuffer();
- *(statePtr->regReset) = NET_DF_RESET_RESET;
- Mach_EmptyWriteBuffer();
- *(statePtr->regReset) = NET_DF_CLEAR;
- Mach_EmptyWriteBuffer();
-
- NetDFAssertState(statePtr, NET_DF_STATE_RESETTING);
- printf("DEC FDDI: RESETTING -> ");
-
- statePtr->flags |= NET_DF_FLAGS_RESETTING;
- for (i = 0; i < 50000000; i++) {
- test = *(statePtr->regEvent) & NET_DF_EVENT_STATE_CHANGE;
- if (test) {
- status = *(statePtr->regStatus) & NET_DF_STATUS_ADAPTER_STATE;
- if (status == NET_DF_STATE_UNINITIALIZED) {
- printf("UNINITIALIZED -> ");
- break;
- }
- }
- }
- test = *(statePtr->regEvent) & NET_DF_EVENT_STATE_CHANGE;
- if (!test) {
- NetDFPrintRegContents(statePtr);
- panic("DEC FDDI: Adapter will not initialize!\n");
- /*
- * should read the TEST_ID field of PORT_STATUS to see which
- * self-test failed
- */
- }
- NET_DF_ENABLE_ALL_INT(*(statePtr->regMask));
- NET_DF_CLEAR_ALL_EVENTS(*(statePtr->regEvent));
-
- /*
- * Reset the COMMAND and UNSOLICITED rings before we execute commands.
- */
- statePtr->comNextPtr = statePtr->comRingPtr;
- statePtr->unsolNextDescPtr = statePtr->unsolFirstDescPtr;
- statePtr->lastUnsolCnt = 0;
-
- printf("INITIALIZED\n");
- NetDFDoInitCommand(statePtr);
- /*
- * Once the INIT command completes, we can initialize the HOST RCV,
- * SMT RCV, RMC XMT, and SMT XMT rings.
- */
- NetDFRecvInit(statePtr);
- NetDFXmitInit(statePtr);
-
- /*
- * Now that the rings are initialized, massage the adapter into the
- * RUNNING state and connect to the network. Please please please.
- */
- status = NetDFDoModcamCommand(statePtr);
- if (status != SUCCESS) {
- goto done;
- }
- status = NetDFDoParamCommand(statePtr);
- if (status != SUCCESS) {
- goto done;
- }
- status = NetDFDoModpromCommand(statePtr);
- if (status != SUCCESS) {
- goto done;
- }
-
- NET_DF_CLEAR_ALL_EVENTS(*(statePtr->regEvent));
-
- done:
- statePtr->numResets++;
- statePtr->flags &= ~NET_DF_FLAGS_RESETTING;
- if (status == SUCCESS) {
- interPtr->flags = NET_IFLAGS_RUNNING;
- } else {
- interPtr->flags &= ~NET_IFLAGS_RUNNING;
- }
- Sync_Broadcast(&statePtr->doingReset);
- return;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFRestart --
- *
- * Reinitialize the DEC FDDI adapter. Assumes that the
- * interface mutex is held.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Resets the adapter.
- *
- *----------------------------------------------------------------------
- */
- void
- NetDFRestart(interPtr)
- Net_Interface *interPtr; /* Interface to restart. */
- {
-
- NetDFState *statePtr = (NetDFState *) interPtr->interfaceData;
-
- /*
- * Drop the current packet so the sender doesn't get hung.
- */
- DFprintf("DEC FDDI: Dropping current packet.\n");
- NetDFXmitDrop(statePtr);
-
- /*
- * Reset the world.
- */
- NetDFReset(interPtr);
-
- /*
- * Restart transmission of packets.
- */
- DFprintf("DEC FDDI: Restarting transmission queue.\n");
- NetDFXmitRestart(statePtr);
-
- return;
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFRestartCallback --
- *
- * This routine is called by the Proc_ServerProc during the
- * callback to reset the adapter.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The adapter is reset.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- static void
- NetDFRestartCallback(data, infoPtr)
- ClientData data; /* Ptr to the interface to reset. */
- Proc_CallInfo *infoPtr; /* Unused. */
- {
- Net_DFRestart((Net_Interface *) data);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * Net_DFRestart --
- *
- * This is a version of the reset routine that can be called
- * from outside the module since it locks the mutex.
- *
- * Results:
- *
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- void
- Net_DFRestart(interPtr)
- Net_Interface *interPtr; /* Interface to reset. */
- {
- register NetDFState *statePtr;
-
- statePtr = (NetDFState *) interPtr->interfaceData;
-
- MASTER_LOCK(&interPtr->mutex);
-
- if (statePtr->flags & NET_DF_FLAGS_RESETTING) {
- MAKE_NOTE("Restarting while restarting. Doing nothing.");
- goto exit;
- }
-
- MAKE_NOTE("_Restarting FDDI.");
- /*
- * If we are at interrupt level we have to do a callback to reset
- * the adapter since we can't wait for the response from
- * the adapter (there may not be a current process and we can't
- * get the interrupt).
- */
- if (Mach_AtInterruptLevel()) {
- Proc_CallFunc(NetDFRestartCallback, (ClientData) interPtr, 0);
- } else {
- (void) NetDFRestart(interPtr);
- }
- exit:
- MASTER_UNLOCK(&interPtr->mutex);
- }
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFIntr --
- *
- * Process an interrupt from the DEC FDDI adapter.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- /* ARGSUSED */
- void
- NetDFIntr(interPtr, polling)
- Net_Interface *interPtr; /* Interface to process. */
- Boolean polling; /* TRUE if are being polled instead of
- * processing an interrupt. */
- {
- register NetDFState *statePtr;
- register volatile unsigned short event;
- int i;
- List_Links *xmitElem;
- unsigned short status;
- ReturnStatus statusRcv, statusXmt;
- static Boolean shouldNotice = FALSE;
- static Boolean halt = FALSE;
- Boolean test;
- unsigned short result;
-
-
- statePtr = (NetDFState *) interPtr->interfaceData;
-
- if (statePtr->flags & NET_DF_FLAGS_RESETTING) {
- test = *(statePtr->regEvent) & NET_DF_EVENT_STATE_CHANGE;
- if (test) {
- result = *(statePtr->regStatus) & NET_DF_STATUS_ADAPTER_STATE;
- if (result == NET_DF_STATE_UNINITIALIZED) {
- /*
- * Put code here to wakeup process waiting in the
- * reset code.
- */
- } else {
- NetDFPrintRegContents(statePtr);
- panic("DEC FDDI: Adapter did not initialize during reset!\n");
- }
- } else {
- /*
- * Clear those pesky events that aren't what we are looking for.
- */
- *(statePtr->regEvent) = test;
- }
- goto exit;
- }
-
- #ifdef NOTDEF
- /*
- * useful for halting in the interrupt routine when debugging
- */
-
- if (halt == TRUE) {
- NET_DF_CLEAR_ALL_EVENTS(*statePtr->regEvent);
- NET_DF_DISABLE_ALL_INT(*statePtr->regMask);
- Mach_EmptyWriteBuffer();
-
- goto exit;
- }
- #endif
- #ifdef lint
- halt == true;
- #endif
- event = *(statePtr->regEvent);
- *(statePtr->regEvent) = event;
- if (shouldNotice && !(event & NET_DF_EVENT_XMT_PKT_DONE)) {
- MAKE_NOTE("clearly missed the transmit done.");
- shouldNotice = FALSE;
- }
- status = *(statePtr->regStatus);
- DFprintf("\nDEC FDDI: NetDFIntr --->");
- /*
- * LINK_STATUS_CHANGE tells us either that we just connected
- * to the ring, or that the ring has become unavailable.
- * We are not supposed to transmit USER_LLC or USER_SMT
- * packets, although we must handle all others.
- */
- if (event & NET_DF_EVENT_LINK_STATUS_CHANGE) {
- DFprintf("DEC FDDI: Interrupt: Link status changed to 0x%x.\n",
- status & NET_DF_STATUS_LINK_STATUS);
- if ((status & NET_DF_STATUS_LINK_STATUS) == NET_DF_LINK_UNAVAILABLE) {
- printf("DEC FDDI: Link became unavailable.\n");
- halt = TRUE;
- } else {
- printf("DEC FDDI: Link now available.\n");
- }
- }
- /*
- * For the PM_PARITY_ERROR and MB_PARITY_ERROR, nothing seems
- * to happen....so do nothing. For NXM_ERROR, the adapter
- * will have transitioned into the HALTED state.
- */
- if (event & NET_DF_EVENT_PM_PARITY_ERROR) {
- DFprintf("DEC FDDI: Interrupt: PM parity error.\n");
- }
- if (event & NET_DF_EVENT_MB_PARITY_ERROR) {
- DFprintf("DEC FDDI: Interrupt: MB parity error.\n");
- }
- if (event & NET_DF_EVENT_NXM_ERR) {
- DFprintf("DEC FDDI: Interrupt: Non existant memory error.\n");
- }
- /*
- * Should be a rare event.
- */
- if (event & NET_DF_EVENT_FLUSH_TX) {
- DFprintf("DEC FDDI: Interrupt: Flush XMT rings requested.\n");
- }
- /*
- * The adapter has changed state. Most likely this means that
- * we have halted for some reason.
- */
- if (event & NET_DF_EVENT_STATE_CHANGE) {
- DFprintf("DEC FDDI: Interrupt: Adapter state changed to 0x%x.\n",
- *(statePtr->regStatus) & NET_DF_STATUS_ADAPTER_STATE);
- }
- if ((*(statePtr->regStatus) & NET_DF_STATUS_ADAPTER_STATE)
- == NET_DF_STATE_HALTED) {
- printf("DEC FDDI: Adapter halted.\n");
- if (!(statePtr->flags & NET_DF_FLAGS_HALTED)) {
-
- #ifdef NOTDEF
- NetDFPrintRegContents(statePtr);
- NetDFPrintErrorLog(statePtr);
-
- NET_DF_CLEAR_ALL_EVENTS(*statePtr->regEvent);
- NET_DF_DISABLE_ALL_INT(*statePtr->regMask);
- Mach_EmptyWriteBuffer();
-
- NetDFPrintDebugRing(statePtr);
- DBG_CALL;
- Mach_EmptyWriteBuffer();
- Mach_EmptyWriteBuffer();
- halt = TRUE;
- #endif
- /*
- * Note that this reset does not lock the mutex.
- */
- NetDFRestart(interPtr);
- }
- goto exit;
- }
- /*
- * An unsolicited event has arrived. Just process it and
- * report it.
- */
- if (event & NET_DF_EVENT_UNS_POLL_DEMAND) {
- DFprintf("DEC FDDI: Interrupt: unsolicited event.\n");
- ProcessUnsolicited(statePtr);
- }
- /*
- * A command has finished. And there was rejoicing.
- */
- if (event & NET_DF_EVENT_CMD_DONE) {
- DFprintf("DEC FDDI: Interrupt: Command done.\n");
- }
- if ((*(statePtr->regStatus) & NET_DF_STATUS_ADAPTER_STATE)
- != NET_DF_STATE_RUNNING) {
- /*
- * If we're not in in the HALTED state and we're not in the
- * RUNNING state, then don't process any of the other events.
- */
- MAKE_NOTE("stopped processing events --> not in running state");
- goto exit;
- }
- statusRcv = statusXmt = SUCCESS;
- /*
- * We have finished transmitting a packet, so send another
- * one if there are any left.
- */
- if ((*(statePtr->regEvent) & NET_DF_EVENT_XMT_PKT_DONE)
- && !(event & NET_DF_EVENT_XMT_PKT_DONE)) {
- MAKE_NOTE("skipped a transmit done, level 1");
- shouldNotice = TRUE;
- }
- if (event & NET_DF_EVENT_XMT_PKT_DONE) {
- DFprintf("DEC FDDI: Interrupt: XMT packet done.\n");
- MAKE_NOTE("---before XMT done---");
- statusXmt = NetDFXmitDone(statePtr);
- MAKE_NOTE("---after XMT done---");
- }
- if ((*(statePtr->regStatus) & NET_DF_STATUS_ADAPTER_STATE)
- == NET_DF_STATE_HALTED) {
- MAKE_NOTE("---halted after XMT done---");
- }
- /*
- * We have received a packet, so give the contents to the lucky
- * process that's waiting for it.
- */
- if (event & NET_DF_EVENT_RCV_POLL_DEMAND) {
- DFprintf("DEC FDDI: Interrupt: RCV poll demand.\n");
- statusRcv = NetDFRecvProcess(FALSE, statePtr);
- MAKE_NOTE("---after RCV done---");
- }
- /*
- * The adapter wants us to transfer a SMT packet from the
- * SMT_XMT ring to the RMC_XMT ring. Oblige it.
- */
- if (event & NET_DF_EVENT_SMT_XMT_POLL_DEMAND) {
- DFprintf("DEC FDDI: Interrupt: SMT XMT poll demand.\n");
-
- MAKE_NOTE("SMT XMT poll demand");
- NetDFSmtOutput(interPtr);
- }
-
- if (netDFDebug == NET_DF_DEBUG_ON) {
- i = 0;
- LIST_FORALL(statePtr->xmitList, xmitElem) {
- i++;
- }
- DFprintf("DEC FDDI: <--------------- XMT Queue: %d\n", i);
- }
-
- if (statusRcv != SUCCESS || statusXmt != SUCCESS) {
- if (statusRcv != SUCCESS) {
- MAKE_NOTE("RCV wasn't successful.");
- }
- if (statusXmt != SUCCESS) {
- MAKE_NOTE("XMT wasn't successful.");
- }
- }
- exit:
- return;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFGetStats --
- *
- * Return the statistics for the interface.
- *
- * Results:
- * A pointer to the statistics structure.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- ReturnStatus
- NetDFGetStats(interPtr, statPtr)
- Net_Interface *interPtr; /* Current interface. */
- Net_Stats *statPtr; /* Statistics to return. */
- {
- NetDFState *statePtr = (NetDFState *) interPtr->interfaceData;
-
- MASTER_LOCK(&interPtr->mutex);
-
- if (statePtr->flags & NET_DF_FLAGS_RESETTING) {
- MAKE_NOTE("Process waiting in NetDFIOControl while resetting.\n");
- do {
- Sync_MasterWait(&statePtr->doingReset, &interPtr->mutex, FALSE);
- } while (statePtr->flags & NET_DF_FLAGS_RESETTING);
- }
-
- MAKE_NOTE("Returning FDDI stats.");
- statPtr->fddi = statePtr->stats;
-
- MASTER_UNLOCK(&interPtr->mutex);
- return SUCCESS;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * NetDFIOControl --
- *
- * Perform ioctls for the adapter. Right now we don't support any.
- *
- * Results:
- * DEV_INVALID_ARG
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
- /*ARGSUSED*/
- ReturnStatus
- NetDFIOControl(interPtr, ioctlPtr, replyPtr)
- Net_Interface *interPtr; /* Interface on which to perform ioctl. */
- Fs_IOCParam *ioctlPtr; /* Standard I/O Control parameter block */
- Fs_IOReply *replyPtr; /* Size of outBuffer and returned signal */
- {
- register NetDFState *statePtr;
- ReturnStatus status;
-
- statePtr = (NetDFState *)interPtr->interfaceData;
-
- DFprintf("NetDFIOControl: command = %d\n", ioctlPtr->command);
- if ((ioctlPtr->command & ~0xffff) != IOC_FDDI) {
- return DEV_INVALID_ARG;
- }
-
- MASTER_LOCK(&interPtr->mutex);
-
- if (statePtr->flags & NET_DF_FLAGS_RESETTING) {
- MAKE_NOTE("Process waiting in NetDFIOControl while resetting.\n");
- do {
- Sync_MasterWait(&statePtr->doingReset, &interPtr->mutex, FALSE);
- } while (statePtr->flags & NET_DF_FLAGS_RESETTING);
- }
-
- status = SUCCESS;
- switch(ioctlPtr->command) {
- case IOC_FDDI_RESET:
- MASTER_UNLOCK(&interPtr->mutex);
- statePtr->flags &= ~NET_DF_FLAGS_HALTED;
- Net_DFRestart(interPtr);
- MASTER_LOCK(&interPtr->mutex);
- status = SUCCESS;
- break;
- case IOC_FDDI_DEBUG:
- if (netDFDebug == NET_DF_DEBUG_ON) {
- printf("DEC FDDI: Debug turned off.\n");
- netDFDebug = NET_DF_DEBUG_OFF;
- } else {
- printf("DEC FDDI: Debug turned on.\n");
- netDFDebug = NET_DF_DEBUG_ON;
- }
- break;
- case IOC_FDDI_REG_CONTENTS: {
- Dev_FDDIRegContents *regContentsPtr;
-
- regContentsPtr = (Dev_FDDIRegContents *)ioctlPtr->outBuffer;
- if (regContentsPtr == NULL) {
- status = FAILURE;
- goto exit;
- }
- regContentsPtr->regReset = *(statePtr->regReset);
- regContentsPtr->regCtrlA = *(statePtr->regCtrlA);
- regContentsPtr->regCtrlB = *(statePtr->regCtrlB);
- regContentsPtr->regStatus = *(statePtr->regStatus);
- regContentsPtr->regEvent = *(statePtr->regEvent);
- regContentsPtr->regMask = *(statePtr->regMask);
- break;
- }
- case IOC_FDDI_ERR_LOG: {
- Dev_FDDIErrLog *errLogPtr;
-
- errLogPtr = (Dev_FDDIErrLog *)ioctlPtr->outBuffer;
- if (errLogPtr == NULL) {
- status = FAILURE;
- goto exit;
- }
- errLogPtr->internal = *(statePtr->errLogPtr +
- NET_DF_MACH_ERR_INTERNAL_OFFSET);
- errLogPtr->external = *(statePtr->errLogPtr +
- NET_DF_MACH_ERR_EXTERNAL_OFFSET);
- break;
- }
- case IOC_FDDI_SEND_PACKET: {
- Dev_FDDISendPacket *packetPtr;
- Net_FDDIHdr *fddiHdrPtr;
- Net_ScatterGather *scatterPtr;
-
- packetPtr = (Dev_FDDISendPacket *)ioctlPtr->inBuffer;
- if (packetPtr == NULL) {
- status = FAILURE;
- goto exit;
- }
- fddiHdrPtr = &statePtr->headerArray[statePtr->scatterIndex];
- scatterPtr = &statePtr->scatterArray[statePtr->scatterIndex];
- IncScatterIndex(statePtr);
-
- fddiHdrPtr->prh[0] = NET_DF_PRH0;
- fddiHdrPtr->prh[1] = NET_DF_PRH1;
- fddiHdrPtr->prh[2] = NET_DF_PRH2;
- fddiHdrPtr->frameControl = NET_DF_FRAME_HOST_LLC;
- NET_FDDI_ADDR_COPY(packetPtr->dest, fddiHdrPtr->dest);
-
- scatterPtr->bufAddr = packetPtr->buffer;
- scatterPtr->length = packetPtr->length;
- scatterPtr->mutexPtr = NULL;
- scatterPtr->done = FALSE;
-
- /*
- * NetDFOutput locks the mutex.
- */
- MASTER_UNLOCK(&interPtr->mutex);
- status = NetDFOutput(interPtr, fddiHdrPtr, scatterPtr, 1, FALSE, NIL);
- MASTER_LOCK(&interPtr->mutex);
-
- break;
- }
- case IOC_FDDI_FLUSH_XMT_Q: {
- printf("DEC FDDI: Dropping current packet.\n");
- NetDFXmitDrop(statePtr);
- printf("DEC FDDI: Flushing transmit queue.\n");
- NetDFXmitFlushQ(statePtr);
- break;
- }
- case IOC_FDDI_ADDRESS: {
- Dev_FDDILinkAddr *infoPtr;
-
- infoPtr = (Dev_FDDILinkAddr *)ioctlPtr->outBuffer;
- if (infoPtr == NULL) {
- status = FAILURE;
- goto exit;
- }
- NET_FDDI_ADDR_COPY(statePtr->fddiAddress, infoPtr->source);
- break;
- }
- case IOC_FDDI_RPC_ECHO: {
- Dev_FDDIRpcEcho *echoPtr;
- Dev_FDDIRpcEchoReturn *returnPtr;
- char *bufPtr;
-
- echoPtr = (Dev_FDDIRpcEcho *)ioctlPtr->inBuffer;
- if (echoPtr == NULL || echoPtr == (Dev_FDDIRpcEcho *)NULL) {
- status = FAILURE;
- goto exit;
- }
- returnPtr = (Dev_FDDIRpcEchoReturn *)ioctlPtr->outBuffer;
- if (returnPtr == NULL || returnPtr == (Dev_FDDIRpcEchoReturn *)NULL) {
- status = FAILURE;
- goto exit;
- }
- bufPtr = (char *)malloc(echoPtr->packetSize);
- if (echoPtr->printSyslog == TRUE) {
- status = Rpc_EchoTest(echoPtr->serverID, echoPtr->numEchoes,
- echoPtr->packetSize, bufPtr, bufPtr,
- (Time *)NIL);
- } else {
- status = Rpc_EchoTest(echoPtr->serverID, echoPtr->numEchoes,
- echoPtr->packetSize, bufPtr, bufPtr,
- &returnPtr->rpcTime);
- }
- free(bufPtr);
- break;
- }
- case IOC_FDDI_HALT: {
- statePtr->flags |= NET_DF_FLAGS_HALTED;
- *(statePtr->regCtrlA) |= NET_DF_CTRLA_HALT;
- break;
- }
- case IOC_FDDI_STATS: {
- Dev_FDDIStats *statsPtr;
-
- statsPtr = (Dev_FDDIStats *)ioctlPtr->outBuffer;
- if (statsPtr == NULL || statsPtr == (Dev_FDDIStats *)NIL) {
- status = DEV_INVALID_ARG;
- goto exit;
- }
- bcopy((Address)&statePtr->stats, (Address)statsPtr,
- sizeof(Dev_FDDIStats));
- break;
- }
- default:
- printf("NetDFIOControl: unknown ioctl 0x%x\n", ioctlPtr->command);
- }
-
- exit:
- MASTER_UNLOCK(&interPtr->mutex);
- return status;
- }
-